package com.quanyan.club.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.club.constants.ClubConstants;
import com.quanyan.club.constants.ClubMemberPriorityConstants;
import com.quanyan.club.entity.RespClubXpLevelMsg;
import com.quanyan.club.entity.db.*;
import com.quanyan.club.entity.vo.req.ReqClubMemberEditAll;
import com.quanyan.club.entity.RespClubMember;
import com.quanyan.club.mapper.*;
import com.quanyan.club.mq.ClubMedalMsg;
import com.quanyan.club.mq.producer.ClubXpLevelProducer;
import com.quanyan.club.mq.producer.impl.ClubMedalProducerImpl;
import com.quanyan.club.service.*;
import com.quanyan.club.thread.ClubMemberSolrIndexThread;
import com.quanyan.comment.enums.TaskEnum;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.constants.MqConstants;
import com.quanyan.common.enums.SysCategoryEnum;
import com.quanyan.common.enums.SysClubMedalConditionEnum;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.Limit;
import com.quanyan.common.utils.ObjectUtil;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.mq.client.QcMsgClient;
import com.quanyan.mq.client.reqeust.MqRequestMsg;
import com.quanyan.mq.client.response.MqResponse;
import com.quanyan.search.entity.request.ReqClubMemberInfo;
import com.quanyan.search.entity.response.ClubMemberResponse;
import com.quanyan.search.service.impl.ClubMemberSearchServiceImpl;
import com.quanyan.user.mq.UserTaskMsg;
import com.quanyan.user.response.RespUserInfoBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by zhuo.shi on 2016/6/1.
 * 俱乐部成员服务类：
 * 1. 申请加入俱乐部
 * 2. 退出俱乐部
 * 3. 邀请用户加入俱乐部
 * 4. 俱乐部成员列表
 * 5. 变更俱乐部成员职位、标签
 */
@Service("clubMemberService")
public class ClubMemberServiceImpl extends BaseServiceImpl implements ClubMemberService {

    private static Logger logger = LoggerFactory.getLogger(ClubMemberServiceImpl.class);

    @Autowired
    private ThreadPoolTaskExecutor executor;

    @Autowired
    private ClubIntegralService clubIntegralService;

    private final String CREATE_TEAM = "CREATE_TEAM";
    private final String EDIT_MEMBER = "EDIT_MEMBER";
    @Autowired
    private TbClubMapper clubMapper;
    @Autowired
    private TbClubMemberMapper clubMemberMapper;
    @Autowired
    private ClubMemberMapper customClubMemberMapper;
    @Autowired
    private TbClubMemberApplyMapper clubMemberApplyMapper;
    @Autowired
    private TbClubOnlineMemberAccountMapper clubOnlineMemberAccountMapper;
    @Autowired
    private TbClubOfflineMemberAccountMapper clubOfflineMemberAccountMapper;

    @Autowired
    @Qualifier("personCenterTaskClient")
    private QcMsgClient qcMsgClient;
    @Autowired
    private CppService cppService;

    private ClubMemberSearchServiceImpl clubMemberSearchService;

    @Autowired
    private ClubFinanceMgmService clubFinanceMgmService;

    @Autowired
    private ClubXpLevelProducer clubXpLevelProducer;
    @Autowired
    private ClubXpLevelService clubXpLevelService;
    @Autowired
    private ClubMedalProducerImpl clubMedalProducerImpl;
    @Autowired
    private ClubActivityMapper clubActivityMapper;

    @PostConstruct
    protected  void init(){
        clubMemberSearchService = new ClubMemberSearchServiceImpl();
        clubMemberSearchService.setURL(searchCloudUrl);
    }

    /**
     * 俱乐部管理员列表（包含主席、管理员、财务管理员）
     * @param clubId        俱乐部ID
     * @return
     */
    @Override
    public List<RespClubMember> listClubAdministors(Integer uid, Integer clubId) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andRoleCodeIn(Arrays.asList(
                        Constants.ClubRole.CLUB_ROLE_PRESIDENT,
                        Constants.ClubRole.ROLE_CLUB_ADMIN,
                        Constants.ClubRole.ROLE_CLUB_FINANCIAL))
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        //管理员按照等级排序
        tbClubMemberExample.setOrderByClause(" id, priority asc");
        List<TbClubMember> tbClubMembers = clubMemberMapper.selectByExample(tbClubMemberExample);
        List<RespClubMember> respClubMembers = this.convert2RespClubMember(uid, tbClubMembers, false);
        return respClubMembers;
    }

    /**
     * 俱乐部所有成员列表
     * @param clubId        俱乐部ID
     * @param showFund      是否返回俱乐部成员在俱乐部中的资金
     * @param pageNo        页码
     * @param pageSize      每页记录条数
     * @return
     */
    @Override
    public List<RespClubMember> listClubMembers(Integer uid, Integer clubId, Boolean showFund, Boolean showAdmin, Integer pageNo, Integer pageSize) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        TbClubMemberExample.Criteria criteria =  tbClubMemberExample.createCriteria();
        criteria.andClubIdEqualTo(clubId)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        if (!showAdmin){
            criteria.andRoleCodeNotIn(Arrays.asList(
                    Constants.ClubRole.CLUB_ROLE_PRESIDENT,
                    Constants.ClubRole.ROLE_CLUB_ADMIN,
                    Constants.ClubRole.ROLE_CLUB_FINANCIAL));
        }
        //管理员按照等级排序
        tbClubMemberExample.setOrderByClause(" id, priority asc");
        Limit limit = Limit.buildLimit(pageNo, pageSize);
        tbClubMemberExample.setLimit(limit);
        List<TbClubMember> tbClubMembers = clubMemberMapper.selectByExample(tbClubMemberExample);
        List<RespClubMember> respClubMembers = this.convert2RespClubMember(uid, tbClubMembers, showFund);
        return respClubMembers;
    }

    /**
     * 俱乐部所有成员人数
     * @param clubId        俱乐部ID
     * @return
     */
    @Override
    public Integer countClubMembers(@NotNull Integer clubId, Boolean showAdmin) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        TbClubMemberExample.Criteria criteria =  tbClubMemberExample.createCriteria();
        criteria.andClubIdEqualTo(clubId)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        if (!showAdmin){
            criteria.andRoleCodeNotIn(Arrays.asList(
                    Constants.ClubRole.CLUB_ROLE_PRESIDENT,
                    Constants.ClubRole.ROLE_CLUB_ADMIN,
                    Constants.ClubRole.ROLE_CLUB_FINANCIAL));
        }

        return clubMemberMapper.countByExample(tbClubMemberExample);
    }

    /**
     * 俱乐部代表队成员列表
     * @param clubId        俱乐部ID
     * @param pageNo        页码
     * @param pageSize      每页记录条数
     * @return
     */
    @Override
    public List<RespClubMember> listClubTeamMembers(Integer uid, Integer clubId, Integer pageNo, Integer pageSize) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andIsTeamMemberEqualTo(Constants.YES)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        Limit limit = Limit.buildLimit(pageNo, pageSize);
        tbClubMemberExample.setLimit(limit);
        //管理员按照等级排序
        tbClubMemberExample.setOrderByClause(" id, priority asc");
        List<TbClubMember> tbClubMembers = clubMemberMapper.selectByExample(tbClubMemberExample);
        List<RespClubMember> respClubMembers = this.convert2RespClubMember(uid, tbClubMembers, false);
        return respClubMembers;
    }

    /**
     * 俱乐部代表队成员人数
     * @param clubId        俱乐部ID
     * @return
     */
    @Override
    public Integer countClubTeamMembers(Integer clubId) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andIsTeamMemberEqualTo(Constants.YES)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        return clubMemberMapper.countByExample(tbClubMemberExample);
    }

    /**
     * 是否是某个俱乐部成员
     * @param uid       用户ID
     * @param clubId    俱乐部ID
     * @return
     */
    @Override
    public Boolean isClubMember(Integer uid, Integer clubId) {
        if (uid == null || clubId == null){
            return false;
        }
        //判断是否已经加入此俱乐部
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().
                andClubIdEqualTo(clubId).
                andUidEqualTo(uid).
                andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        int count = clubMemberMapper.countByExample(tbClubMemberExample);
        return count > 0;
    }

    /**
     * 是否是某个俱乐部管理员
     * @param uid       用户ID
     * @param clubId    俱乐部ID
     * @return
     */
    @Override
    public Boolean isClubAdminMember(Integer uid, Integer clubId) {
        if (uid == null || clubId == null){
            return false;
        }
        //判断是否已经加入此俱乐部且是管理层以上
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().
                andClubIdEqualTo(clubId).
                andUidEqualTo(uid).
                andPriorityIn(Arrays.asList(1,2,3)).
                andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        int count = clubMemberMapper.countByExample(tbClubMemberExample);
        return count > 0;
    }

    @Override
    public Boolean isClubMasterMember(Integer uid, Integer clubId) {
        if (uid == null || clubId == null){
            return false;
        }
        //判断是否已经加入此俱乐部且是主席
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().
                andClubIdEqualTo(clubId).
                andUidEqualTo(uid).
                andPriorityEqualTo(1).
                andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        int count = clubMemberMapper.countByExample(tbClubMemberExample);
        return count > 0;
    }

    /**
     * 申请加入俱乐部
     * @param uid           申请用户的ID
     * @param clubId        俱乐部ID
     * @param remark        申请人留言
     * @return
     */
    @Override
    public Boolean applyJoinClub(Integer uid, Integer clubId, String remark,int larkAppId) {

        boolean isApplyScucces = false;
        TbClub club = clubMapper.selectByPrimaryKey(clubId);
        if (club == null || club.getIsDelete() == 1){
            throw new BizException("俱乐部已解散！");
        }
        RespUserInfoBase user = getUserInfoBase(uid);
        if (club.getJoinType() == Constants.ZERO){
            //无需验证，直接加入俱乐部
            isApplyScucces = this.addClubMemberApply(uid, remark, clubId, null, ClubConstants.APPLY_TYPE_JOIN);
            if (isApplyScucces && !isClubMember(uid,clubId)){
                TbClubMember clubMember = new TbClubMember();
                clubMember.setClubId(clubId);
                clubMember.setUid(uid);
                clubMember.setIsTeamMember(Constants.NO);
                clubMember.setRoleCode(Constants.ClubRole.ROLE_CLUB_MEMBER);
                clubMember.setRoleName("普通成员");
                clubMember.setPriority(ClubMemberPriorityConstants.ROLE_CLUB_MEMBER_PRIORITY);
                int ret = clubMemberMapper.insertSelective(clubMember);
                if (ret == 1){
                    initClubMemberAccount(clubId, uid);
                    //添加到索引
                    //insertClubMemberIndex(clubId, uid);

                    //将此用户拉到俱乐部聊天室
                    cppService.addOrDelIMGroupMember(club.getUid(),clubId, club.getImGroupid(), Arrays.asList(new Integer[]{uid}), true);
                    //推送加入俱乐部消息
                    cppService.pushJoinClubMsg(club, Arrays.asList(uid), user, larkAppId);
                    pushUsercenterTaskMsg(uid);
                    //发送俱乐部勋章mq消息
                    this.sendClubMedalMqMsg(clubId,uid,0,club.getClubType());

                    //推送消息给俱乐部成员，xx加入了俱乐部
                    this.pushJoinClubMsg(clubId, uid);
                }
            }
        }else {
            isApplyScucces = this.addClubMemberApply(uid, remark, clubId, null, ClubConstants.APPLY_TYPE_ASK);   //申请加入
            if (isApplyScucces) {
                //推申请加入送消息给俱乐部主席、管理员、财务管理员
                List<RespClubMember> members = listClubAdministors(uid, club.getId());
                List<Integer> adminIds = new ArrayList<>();
                for (RespClubMember member : members){
                    if (member == null || member.getUid() == 0){
                        continue;
                    }
                    adminIds.add(member.getUid());
                }
                cppService.pushClubMemberJoinMsg(user, club, adminIds, remark, false, 0, true);
            }
        }
        return isApplyScucces;
    }

    @Override
    public Boolean isApplyJoinClub(Integer uid, Integer clubId, Integer inviteUid) {
        TbClubMemberApplyExample example = new TbClubMemberApplyExample();
        TbClubMemberApplyExample.Criteria criteria = example.createCriteria();
        criteria.andClubIdEqualTo(clubId)
                .andUidEqualTo(uid)
                .andStatusEqualTo(Constants.BYTE_ONE)        //已审核通过的不可再邀请
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        if (inviteUid != null ){
            criteria.andInviteUidEqualTo(inviteUid);
        }
        return clubMemberApplyMapper.countByExample(example) > 0;
    }

    /**
     * 加入到俱乐部，两种情况：
     * 1. 俱乐部的管理员同意申请加入俱乐部的用户
     * 2. 被邀请的用户同意加入俱乐部
     *
     * @param uid           申请或被邀请的用户ID
     * @param clubId        俱乐部ID
     * @return              是否加入俱乐部成功
     */
    @Override
    @Transactional
    public Boolean agreeJoinClub(Integer uid, Integer clubId, Integer type, int larkAppId) {
        boolean isAgreed = false;
        //新加入到俱乐部
        TbClubMember tbClubMember = new TbClubMember();
        tbClubMember.setUid(uid);
        tbClubMember.setClubId(clubId);
        tbClubMember.setRoleName("普通成员");
        tbClubMember.setRoleCode(Constants.ClubRole.ROLE_CLUB_MEMBER);
        Integer ret = clubMemberMapper.insertSelective(tbClubMember);
        int invitedUid = 0;
        if (ret == Constants.IS_YES){
            isAgreed = true;
            //更新申请加入表
            TbClubMemberApplyExample example2 = new TbClubMemberApplyExample();
            example2.createCriteria()
                    .andStatusIn(Arrays.asList((byte)0, (byte)-1)) //审核中，用户同意中
                    .andClubIdEqualTo(clubId).andUidEqualTo(uid);
            List<TbClubMemberApply> memberApplies = clubMemberApplyMapper.selectByExample(example2);
            if (memberApplies != null && memberApplies.size() > 0){
                TbClubMemberApply apply = new TbClubMemberApply();
                apply.setStatus((byte) 1); //申请同意
                apply.setRemark("已经加入");
                clubMemberApplyMapper.updateByExampleSelective(apply, example2);
                if(null != memberApplies.get(0) && null != memberApplies.get(0).getInviteUid())
                {
                    invitedUid = memberApplies.get(0).getInviteUid();  //邀请人uid
                }
            }
            initClubMemberAccount(clubId, uid);
        }
        if (isAgreed){
            //插入到搜索索引
            RespUserInfoBase user = getUserInfoBase(uid);
            //insertClubMemberIndex(clubId, uid);

            //拉到俱乐部聊天室
            TbClub club = clubMapper.selectByPrimaryKey(clubId);
            if (club != null) {
                boolean success = cppService.addOrDelIMGroupMember(club.getUid(),clubId, club.getImGroupid(), Arrays.asList(new Integer[]{uid}), true);
                if (!success){
                    throw new BizException("加入俱乐部群聊失败，请重试！");
                }
                //推送加入俱乐部消息，开始聊天入口
                //cppService.pushJoinClubMsg(club, Arrays.asList(uid), user);
                if (type == 2){  //被邀请人同意加入俱乐部
                    RespUserInfoBase userInfo = getUserInfoBase(uid);
                    if (userInfo != null){
                        cppService.pushAcceptJoinClubInvite(club, userInfo, Arrays.asList(invitedUid), larkAppId);
                    }
                }
                //推送个人中心任务消息
                pushUsercenterTaskMsg(uid);
                //俱乐部成员加入推送俱乐部勋章消息
                this.sendClubMedalMqMsg(clubId,uid,0,club.getClubType());

                //推送消息给俱乐部成员，xx加入了俱乐部
                this.pushJoinClubMsg(clubId, uid);
            }
        }
        return isAgreed;
    }

    /**
     * 初始化俱乐部成员账户
     */
    @Override
    public void initClubMemberAccount(int clubId, int uid){

        //添加俱乐部成员索引
        executor.submit(new ClubMemberSolrIndexThread(queryClubMember(uid, clubId), getUserInfoBase(uid).getNickName(), clubMemberSearchService, 1));

        TbClubOnlineMemberAccountExample oExample = new TbClubOnlineMemberAccountExample();
        oExample.createCriteria().andClubIdEqualTo(clubId).andUidEqualTo(uid);
        if (clubOnlineMemberAccountMapper.countByExample(oExample) > 0){
            return;
        }
        //生成线上账户
        TbClubOnlineMemberAccount onlineMemberAccount = new TbClubOnlineMemberAccount();
        onlineMemberAccount.setClubId(clubId);
        onlineMemberAccount.setUid(uid);
        onlineMemberAccount.setMoneyTotal(BigDecimal.ZERO);
        onlineMemberAccount.setIsDelete(Constants.IS_DELETE_FALSE);
        clubOnlineMemberAccountMapper.insertSelective(onlineMemberAccount);

        TbClubOfflineMemberAccountExample fExample = new TbClubOfflineMemberAccountExample();
        fExample.createCriteria().andClubIdEqualTo(clubId).andUidEqualTo(uid);
        if (clubOfflineMemberAccountMapper.countByExample(fExample) > 0){
            return;
        }
        //生成下线账户
        TbClubOfflineMemberAccount offlineMemberAccount = new TbClubOfflineMemberAccount();
        offlineMemberAccount.setClubId(clubId);
        offlineMemberAccount.setUid(uid);
        offlineMemberAccount.setMoneyTotal(BigDecimal.ZERO);
        offlineMemberAccount.setIsDelete(Constants.IS_DELETE_FALSE);
        clubOfflineMemberAccountMapper.insertSelective(offlineMemberAccount);

        clubIntegralService.joinClubCountSum(clubId,0);

    }

    private void pushJoinClubMsg(int clubId, int joinUid){

        TbClub tbClub = clubMapper.selectByPrimaryKey(clubId);
        if (tbClub == null){
            return;
        }

        RespUserInfoBase userInfoBase = getUserInfoBase(joinUid);
        if (userInfoBase == null){
            return;
        }
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> clubMembers = clubMemberMapper.selectByExample(example);
        List<Integer> uids = new ArrayList<>();
        for (TbClubMember clubMember : clubMembers){
            if (clubMember.getUid() == joinUid){
                continue;
            }
            uids.add(clubMember.getUid());
        }

        //推送消息给俱乐部成员
        /*int pageSize = 50;      //推送消息只支持每次推送给50个用户
        int pages = uids.size()/pageSize;
        for (int j = 0; j < pages; j++){
            cppService.pushJoinClub2AllMember(tbClub, userInfoBase, uids.subList(j*pageSize, (j+1)*pageSize));
        }
        cppService.pushJoinClub2AllMember(tbClub, userInfoBase, uids.subList(pages*pageSize, uids.size()));
        */
    }

    @Async
    private void pushUsercenterTaskMsg(int uid){
        UserTaskMsg userTaskMsg = new UserTaskMsg();
        userTaskMsg.setTaskId(TaskEnum.TASK_ENUM__ADD_CLUB.getId());
        userTaskMsg.setUid(uid);
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setTopic(Constants.MQ_TOPIC_TASK_TOPIC);
        mqRequestMsg.setTag(Constants.MQ_TOPIC_TASK_TAG);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(userTaskMsg));
        qcMsgClient.asyncSend(mqRequestMsg);
    }

//    @Override
//    @Async
//    public void insertClubMemberIndex(int clubId, int uid){
//        StopWatch sw = new StopWatch();
//        sw.start();
//        //添加俱乐部成员信息索引到slor cloud
//        ClubMemberIndexInfo indexInfo = new ClubMemberIndexInfo();
//        indexInfo.setClub_member_uid(String.valueOf(uid));
//        indexInfo.setClub_id_mem(String.valueOf(clubId));
//        RespUserInfoBase userInfoBase = getUserInfoBase(uid);
//        if (userInfoBase != null) {
//            indexInfo.setClub_member_nickname(userInfoBase.getNickName());
//        }
//        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
//        tbClubMemberExample.createCriteria().
//                andClubIdEqualTo(clubId).
//                andUidEqualTo(uid).
//                andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
//        List<TbClubMember> list = clubMemberMapper.selectByExample(tbClubMemberExample);
//        if (list != null && list.size() > 0){
//            TbClubMember member = list.get(0);
//            indexInfo.setClub_role_name(member.getRoleName());
//            indexInfo.setClub_team_label_name(member.getTeamLabelName());
//        }
//        APIResponse response = clubMemberSearchService.insertDoc(indexInfo);
//        if (response.isRet()){
//            logger.info("添加俱乐部成员索引成功：{}", com.alibaba.fastjson.JSON.toJSONString(indexInfo));
//        }
//        sw.stop();
//        logger.warn("添加俱乐部成员索引clubId={}, uid={}, 花费：{}", clubId ,uid, sw.getTime());
//    }

    /**
     * 拒绝加入俱乐部
     * @param uid       拒绝/被拒绝加入俱乐部的用户uid
     * @param clubId    俱乐部id
     * @return
     */
    @Override
    public Boolean disagreeJoinClub(Integer type, Integer uid, Integer clubId, int larkAppId) {
        TbClubMemberApplyExample example = new TbClubMemberApplyExample();
        example.createCriteria()
                .andStatusEqualTo((byte) 0)
                .andClubIdEqualTo(clubId).andUidEqualTo(uid);
        List<TbClubMemberApply> memberApplies = clubMemberApplyMapper.selectByExample(example);
        if (memberApplies != null && memberApplies.size() > 0){
            TbClubMemberApply apply = new TbClubMemberApply();
            apply.setStatus((byte) 2); //申请被拒绝
            apply.setRemark("拒绝加入");
            int ret = clubMemberApplyMapper.updateByExampleSelective(apply, example);
            if (ret > 0){
                if (type == 1){ //管理员不同意
                    //推送消息
                    TbClub club = clubMapper.selectByPrimaryKey(clubId);
                    cppService.pushClubMemberOutMsg(club.getLogoUrl(), club.getUid(), clubId, "很抱歉，\"" + club.getClubName() + "\"的管理员拒绝了你的加入申请。", Arrays.asList(uid), 3,larkAppId);
                }
                if (type == 2){ //被邀请人拒绝
                    Integer invitedUid = memberApplies.get(0).getInviteUid();  //邀请人uid
                    TbClub club = clubMapper.selectByPrimaryKey(clubId);
                    RespUserInfoBase userInfo = getUserInfoBase(uid);
                    if (userInfo != null) {
                        cppService.pushClubMemberOutMsg(club.getLogoUrl(), uid, clubId, userInfo.getNickName() + "拒绝了你邀请他加入俱乐部\"" + club.getClubName() + "\"的请求。", Arrays.asList(invitedUid), 2,larkAppId);
                    }
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 计算俱乐部成员在俱乐部中资金
     */
    private BigDecimal getClubMemberFund(int uid, int clubId){
        BigDecimal fund = BigDecimal.ZERO;
        TbClubOfflineMemberAccount offline = clubFinanceMgmService.getClubMemberOfflineAccount(uid, clubId);
        if (offline != null){
            fund = fund.add(offline.getMoneyTotal());
        }
        TbClubOnlineMemberAccount online = clubFinanceMgmService.getClubMemberOnlineAccount(uid, clubId);
        if (online != null){
            fund = fund.add(online.getMoneyTotal());
        }
        return fund;
    }

    /**
     * 被管理员踢出俱乐部，在tb_club_member中is_delete字段改为1，此成员在俱乐部中的账户任然保留
     * @param clubId        俱乐部ID
     * @param uid           被踢的用户uid
     * @param currentUid    踢人的用户uid, -1表示后管
     * @return
     */
    @Override
    @Transactional
    public Boolean fuckoutClub(Integer clubId, Integer uid,Integer currentUid,int larkAppId) {

        if (currentUid == null || clubId == 0){
            return false;
        }

        TbClub tbClub = clubMapper.selectByPrimaryKey(clubId);
        if (tbClub.getUid().intValue() == uid){
            throw new BizException("主席不能被踢出俱乐部！");
        }

        //判断本人是否是主席，管理员
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().
                andClubIdEqualTo(clubId).
                andUidEqualTo(currentUid).
                andPriorityIn(Arrays.asList(1, 2, 3)).
                andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        int count = clubMemberMapper.countByExample(tbClubMemberExample);
        if(count == 0 && currentUid != -1){
           throw new BizException("你不是此俱乐部的管理员，不能进行踢人操作！");
        }

        //判断被踢的用户是不是管理员
        tbClubMemberExample.clear();
        tbClubMemberExample.createCriteria().
                andClubIdEqualTo(clubId).
                andUidEqualTo(uid).
                andPriorityIn(Arrays.asList(2, 3));
        int uidUserCount = clubMemberMapper.countByExample(tbClubMemberExample);

        //再判断本人是不是主席，如果是可以踢人，不是不可以
        if(currentUid != -1 && uidUserCount > 0 && tbClub.getUid().intValue() != currentUid){
            throw new BizException("只有主席才能踢管理员！");
        }

        if (getClubMemberFund(uid, clubId).doubleValue() > 0){
            throw new BizException("此成员在俱乐部中会费余额不为0，不能踢出！");
        }

        //从申请表修改is_delete为1
        TbClubMemberApplyExample tbClubMemberApplyExample = new TbClubMemberApplyExample();
        tbClubMemberApplyExample
                .createCriteria()
                .andStatusEqualTo((byte)1) //审核通过加入的
                .andUidEqualTo(uid)
                .andClubIdEqualTo(clubId);
        TbClubMemberApply tbClubMemberApply = new TbClubMemberApply();
        tbClubMemberApply.setIsDelete(Constants.IS_DELETE_TRUE);
        clubMemberApplyMapper.updateByExampleSelective(tbClubMemberApply, tbClubMemberApplyExample);

        TbClubMember tbClubMember = queryClubMember(uid, clubId);
        //从成员表删除
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId)
                .andUidEqualTo(uid);
        int ret = clubMemberMapper.deleteByExample(example);
        if (ret > 0){
            deleteClubMemberAccount(clubId, uid);
            TbClub club = clubMapper.selectByPrimaryKey(clubId);
            //踢出俱乐部聊天室
            cppService.addOrDelIMGroupMember(club.getUid(),clubId, club.getImGroupid(), Arrays.asList(new Integer[]{uid}), false);
            //删除此成员在slor cloud的索引
            executor.submit(new ClubMemberSolrIndexThread(tbClubMember, getUserInfoBase(uid).getNickName(), clubMemberSearchService, 2));
            //推送消息
            cppService.pushClubMemberOutMsg(club.getLogoUrl(), club.getUid(), clubId, "你已经被" + club.getClubName() + "管理员踢出。", Arrays.asList(uid), 2, larkAppId);

            //记录退出动作
            recordClubMemberQuit(clubId, uid, "被管理员踢出", true);
            return true;
        }
        return false;
    }

    /**
     * 退出俱乐部，退出俱乐部，在tb_club_member表里面删除此条记录，在tb_club_member_apply表里面修改is_delete为1
     *
     * @param uid           要退出俱乐部的用户ID
     * @param clubId        俱乐部ID
     * @return              是否退出成功
     */
    @Override
    @Transactional
    public Boolean quitClub(Integer uid, Integer clubId, int larkAppId) {
        if (getClubMemberFund(uid, clubId).doubleValue() > 0){
            throw new BizException("您在此俱乐部中会费余额不为0，暂不能退出！");
        }
        TbClubMember tbClubMember = queryClubMember(uid, clubId);
        // 成员表clubMemberService里面删除
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().andUidEqualTo(uid).andClubIdEqualTo(clubId);
        int ret1 = clubMemberMapper.deleteByExample(tbClubMemberExample);
        if (logger.isDebugEnabled()){
            logger.debug("退出俱乐部:uid={},clubId={},tb_club_member表数据删除.", uid, clubId);
        }
        //从申请表修改is_delete为1
        TbClubMemberApplyExample tbClubMemberApplyExample = new TbClubMemberApplyExample();
        tbClubMemberApplyExample
                .createCriteria()
                .andUidEqualTo(uid)
                .andStatusEqualTo((byte)1) //审核通过加入的
                .andClubIdEqualTo(clubId);
        TbClubMemberApply tbClubMemberApply = new TbClubMemberApply();
        tbClubMemberApply.setIsDelete(Constants.IS_DELETE_TRUE);
        int ret2 = clubMemberApplyMapper.updateByExampleSelective(tbClubMemberApply, tbClubMemberApplyExample);
        if (logger.isDebugEnabled()){
            logger.debug("退出俱乐部:uid={},clubId={},tb_club_member_apply表数据更新is_delete=1.", uid, clubId);
        }
        boolean isQuit = (ret1 > 0 && ret2 > 0);
        if (isQuit){
            deleteClubMemberAccount(clubId, uid);

            RespUserInfoBase user = getUserInfoBase(uid);

            TbClub club = clubMapper.selectByPrimaryKey(clubId);
            //删除此成员在slor cloud的索引
            //clubMemberSearchService.deleteDocById(clubId, uid);
            executor.submit(new ClubMemberSolrIndexThread(tbClubMember, user.getNickName(), clubMemberSearchService, 2));

            //踢出俱乐部聊天室
            cppService.addOrDelIMGroupMember(club.getUid(),clubId, club.getImGroupid(), Arrays.asList(new Integer[]{uid}), false);
            //推送消息给管理员
            List<RespClubMember> administors = listClubAdministors(uid, clubId);
            List<Integer> uids = new ArrayList<>();
            for (RespClubMember admin : administors){
                uids.add(admin.getUid());
            }

            cppService.pushClubMemberOutMsg(user.getIcon(), uid, clubId, user.getNickName() + "已退出俱乐部" + club.getClubName(), uids, 1, larkAppId);

            //记录退出动作
            recordClubMemberQuit(clubId, uid, "用户自己退出", true);
        }
        return isQuit;
    }

    private void deleteClubMemberAccount(int clubId, int uid){
        TbClubOnlineMemberAccountExample onlineexample = new TbClubOnlineMemberAccountExample();
        onlineexample.createCriteria()
                .andClubIdEqualTo(clubId).andUidEqualTo(uid);
//        TbClubOnlineMemberAccount record1 = new TbClubOnlineMemberAccount();
//        record1.setIsDelete(Constants.IS_DELETE_TRUE);
//        clubOnlineMemberAccountMapper.updateByExampleSelective(record1,onlineexample);
        clubOnlineMemberAccountMapper.deleteByExample(onlineexample);

        TbClubOfflineMemberAccountExample offlineexample = new TbClubOfflineMemberAccountExample();
        offlineexample.createCriteria()
                .andClubIdEqualTo(clubId).andUidEqualTo(uid);
//        TbClubOfflineMemberAccount record2 = new TbClubOfflineMemberAccount();
//        record2.setIsDelete(Constants.IS_DELETE_TRUE);
//        clubOfflineMemberAccountMapper.updateByExampleSelective(record2, offlineexample);
        clubOfflineMemberAccountMapper.deleteByExample(offlineexample);
    }


    public int getJoinClubStatus(int clubId, int uid){
        TbClubMemberApplyExample example = new TbClubMemberApplyExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId)
                .andUidEqualTo(uid)
                .andStatusNotIn(Arrays.asList((byte)0, (byte)2)) //0审核中的，可以再次申请；2 拒绝加入的，不显示出来
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMemberApply> applies = clubMemberApplyMapper.selectByExample(example);
        if (applies == null || applies.isEmpty()){
            return -1;
        }
        return applies.get(0).getStatus();
    }

    /**
     * 俱乐部管理员邀请用户加入俱乐部，有一个人被邀请就算邀请成功
     * @param uids          邀请的用户ID，多个用户以英文逗号隔开
     * @param inviteUid      俱乐部管理员（邀请人）ID
     * @param clubId        俱乐部ID
     * @return
     */
    @Override
    @Transactional
    public Boolean inviteClubMember(String uids, Integer inviteUid, Integer clubId, Integer type) {
        String[] uidList = uids.split(",");
        int okSize = 0;
        List<Integer> to = new ArrayList<>();
        for (String s_uid: uidList){
            if (s_uid == null || "".equals(s_uid.trim())){
                continue;
            }
            Integer uid = Integer.valueOf(s_uid);
            boolean ret =  false;
            if (type == 1) {
                ret = this.addClubMemberApply(uid, null, clubId, inviteUid, ClubConstants.APPLY_TYPE_ADMIN_INVITE);     //管理员邀请加入
            }
            if (type == 2){
                ret = this.addClubMemberApply(uid, null, clubId, inviteUid, ClubConstants.APPLY_TYPE_MEMBER_INVITE);    //普通成员邀请
            }
            if (ret) {
                to.add(uid);
                okSize++;   //邀请成功个数
            }
        }

        // 给被邀请的用户推送消息
        RespUserInfoBase inviteUser = getUserInfoBase(inviteUid);   //邀请人用户信息
        TbClub club = clubMapper.selectByPrimaryKey(clubId);        //俱乐部信息
        cppService.pushClubMemberJoinMsg(inviteUser, club, to, "", true, type, false);

        return okSize != 0;
    }

    /**
     * 加入到俱乐部，无论邀请还是申请加入俱乐部，都需要在tb_club_member_apply表生成记录
     *
     * @param uid       用户ID
     * @param clubId    俱乐部ID
     * @param inviteUid  邀请人ID
     */
    @Transactional(propagation = Propagation.REQUIRED)
    private Boolean addClubMemberApply(Integer uid, String remark, Integer clubId, Integer inviteUid, byte type){
        TbClubMemberApplyExample example = new TbClubMemberApplyExample();
        TbClubMemberApplyExample.Criteria criteria = example.createCriteria();
        criteria.andClubIdEqualTo(clubId).andUidEqualTo(uid);
        //生成申请记录
        TbClubMemberApply tbClubMemberApply = new TbClubMemberApply();
        tbClubMemberApply.setClubId(clubId);
        tbClubMemberApply.setUid(uid);
        if (type == ClubConstants.APPLY_TYPE_ASK){
            tbClubMemberApply.setApplyType(ClubConstants.APPLY_TYPE_ASK);  //申请类别：申请
            tbClubMemberApply.setIsAuditing(ClubConstants.AUDITING_YES); //需要审核
            tbClubMemberApply.setStatus((byte)0);   //待审核
            tbClubMemberApply.setRemark(remark);

            criteria.andApplyTypeEqualTo(ClubConstants.APPLY_TYPE_ASK).andIsAuditingEqualTo(ClubConstants.AUDITING_YES).andStatusEqualTo((byte)0);

        }
        if (type == ClubConstants.APPLY_TYPE_ADMIN_INVITE) {
            tbClubMemberApply.setApplyType(ClubConstants.APPLY_TYPE_ADMIN_INVITE);  //申请类别：邀请
            tbClubMemberApply.setIsAuditing(ClubConstants.AUDITING_NO); //不需要审核
            tbClubMemberApply.setStatus((byte)-1); //待审核，用户同意加入
            tbClubMemberApply.setInviteUid(inviteUid);

            criteria.andApplyTypeEqualTo(ClubConstants.APPLY_TYPE_ADMIN_INVITE).andIsAuditingEqualTo(ClubConstants.AUDITING_NO).andStatusEqualTo((byte)-1).andInviteUidEqualTo(inviteUid);
        }
        if (type == ClubConstants.APPLY_TYPE_MEMBER_INVITE) {
            tbClubMemberApply.setApplyType(ClubConstants.APPLY_TYPE_MEMBER_INVITE);  //申请类别：邀请
            tbClubMemberApply.setIsAuditing(ClubConstants.AUDITING_YES); //需要审核
            tbClubMemberApply.setStatus((byte)0); //待审核
            tbClubMemberApply.setInviteUid(inviteUid);

            criteria.andApplyTypeEqualTo(ClubConstants.APPLY_TYPE_MEMBER_INVITE).andIsAuditingEqualTo(ClubConstants.AUDITING_YES).andStatusEqualTo((byte)0).andInviteUidEqualTo(inviteUid);
        }
        if (type == ClubConstants.APPLY_TYPE_JOIN){
            tbClubMemberApply.setApplyType(ClubConstants.APPLY_TYPE_JOIN);  //申请类别：俱乐部无需验证，直接加入
            tbClubMemberApply.setStatus((byte)1); //已审核
            tbClubMemberApply.setIsAuditing(ClubConstants.AUDITING_NO); //不需要审核

            criteria.andApplyTypeEqualTo(ClubConstants.APPLY_TYPE_JOIN).andStatusEqualTo((byte)1).andIsAuditingEqualTo(ClubConstants.AUDITING_NO);
        }
        clubMemberApplyMapper.deleteByExample(example); //先删除再插入新数据，过滤以前的旧数据
        int ret = clubMemberApplyMapper.insertSelective(tbClubMemberApply);
        return ret == Constants.IS_YES;
    }

    /**
     * 将TbClubMember转化为RespClubMember
     *
     * @param tbClubMembers     俱乐部成员表tb_club_member映射类
     * @return
     */
    private List<RespClubMember> convert2RespClubMember(Integer currentUid, List<TbClubMember> tbClubMembers, Boolean showFund){
        List<RespClubMember> respClubMembers = new ArrayList<>();
        if (tbClubMembers != null && tbClubMembers.size() != 0){
            for (TbClubMember tbClubMember : tbClubMembers) {
                RespClubMember respClubMember = new RespClubMember();
                respClubMember.setUid(tbClubMember.getUid());
                respClubMember.setClubId(tbClubMember.getClubId());
                respClubMember.setTeamLabelName(tbClubMember.getTeamLabelName());
                respClubMember.setTeamMember(tbClubMember.getIsTeamMember()==1);
                respClubMember.setMemberLabelName(tbClubMember.getMemberLabelName());
                respClubMember.setRoleName(tbClubMember.getRoleName());
                respClubMember.setRoleCode(tbClubMember.getRoleCode());
                int uid = tbClubMember.getUid();
                TbClub tbClub = clubMapper.selectByPrimaryKey(tbClubMember.getClubId());
                if (tbClub != null) {
                    respClubMember.setClubName(tbClub.getClubName());
                    RespUserInfoBase userInfo = null;
//                    if (currentUid == null){
//                        userInfo = getUserInfoBase(uid);
//                    } else {
                        APIResponse<RespUserInfoBase> response = userServiceFacade.queryUserInfo(uid);//.queryUserInfo(currentUid, uid);
                        if (response != null && response.getData() != null) {
                            userInfo = response.getData();
                        }
                    //}
                    if (userInfo != null){
                        respClubMember.setAvatar(userInfo.getIcon());
                        respClubMember.setGender(userInfo.getGender());
                        respClubMember.setUsername(userInfo.getNickName());
                        respClubMember.setRemarkname(tbClubMember.getRemarkName());
                        respClubMember.setLevel(userInfo.getLevel());
                        respClubMember.setMobile(userInfo.getMobile()); //手机号码
                    }
                }
                if(showFund != null && showFund) {  //显示金额
                    respClubMember.setUsableMoney(this.getUsableMoney(tbClubMember.getClubId(), tbClubMember.getUid()));    //俱乐部成员在俱乐部中可用金额
                }
                respClubMembers.add(respClubMember);
            }
        }
        return respClubMembers;
    }

    /**
     * 获取俱乐部成员在俱乐部中可用金额
     * @param clubId        俱乐部ID
     * @param uid           用户ID
     * @return              可用金额
     */
    private BigDecimal getUsableMoney(@NotNull Integer clubId, @NotNull Integer uid){
        TbClubOnlineMemberAccountExample example = new TbClubOnlineMemberAccountExample();
        example.createCriteria().andUidEqualTo(uid).andClubIdEqualTo(clubId);
        List<TbClubOnlineMemberAccount> onlineMemberAccounts = clubOnlineMemberAccountMapper.selectByExample(example);
        if (onlineMemberAccounts != null && onlineMemberAccounts.size()>0){
            return onlineMemberAccounts.get(0).getMoneyTotal();
        }
        return BigDecimal.ZERO;
    }

    /**
     *  更新俱乐部主席队俱乐部成员的职位和标签编辑
     * @param uid           被编辑的用户ID
     * @param editType      编辑类型：1为职位权限变更，2为俱乐部成员标签变更，3为俱乐部代表队成员标签变更
     * @param clubId        俱乐部ID
     * @param roleCode      俱乐部角色编码（在权限管理模块后台配置）
     * @param roleName      俱乐部角色名称
     * @param label         普通成员或代表队成员标签
     * @return              是否编辑成功
     */
    @Override
    public Boolean updateClubMember(@NotNull Integer uid, @NotNull Integer editType, @NotNull Integer clubId,
                                  String roleCode, String roleName, String label) {
        TbClubMemberExample tbClubMemberExample = new TbClubMemberExample();
        tbClubMemberExample.createCriteria().andUidEqualTo(uid).andClubIdEqualTo(clubId);
        Integer ret = 0;
        if (editType == ClubConstants.ROLE_EDIT){           //角色编辑
            if (StringUtil.isBlankOrNull(roleCode) || StringUtil.isBlankOrNull(roleName)){
                return false;
            }
            TbClubMember tbClubMember = new TbClubMember();
            tbClubMember.setRoleCode(roleCode);
            tbClubMember.setRoleName(roleName);
            //设置俱乐部成员优先级
            if (Constants.ClubRole.CLUB_ROLE_PRESIDENT.equals(roleCode)) {
                tbClubMember.setPriority(ClubMemberPriorityConstants.ROLE_CLUB_PRESIDENT_PRIORITY);
            } else if (Constants.ClubRole.ROLE_CLUB_FINANCIAL.equals(roleCode)) {
                tbClubMember.setPriority(ClubMemberPriorityConstants.ROLE_CLUB_FINANCIAL_PRIORITY);
            } else if (Constants.ClubRole.ROLE_CLUB_ADMIN.equals(roleCode)) {
                tbClubMember.setPriority(ClubMemberPriorityConstants.ROLE_CLUB_ADMIN_PRIORITY);
            } else if (Constants.ClubRole.ROLE_CLUB_MEMBER.equals(roleCode)) {
                tbClubMember.setPriority(ClubMemberPriorityConstants.ROLE_CLUB_MEMBER_PRIORITY);
            }
            ret = clubMemberMapper.updateByExampleSelective(tbClubMember, tbClubMemberExample);
        }
        // TODO :俱乐部经验
        if (editType == ClubConstants.MEMBER_LABEL_EDIT){   //普通成员标签编辑
            TbClubMember tbClubMember = new TbClubMember();
            tbClubMember.setMemberLabelName(label);
            ret = clubMemberMapper.updateByExampleSelective(tbClubMember, tbClubMemberExample);
        }
        if (editType == ClubConstants.TEAM_LABL_EDIT){      //代表队成员标签编辑
            TbClubMemberExample example = new TbClubMemberExample();
            example.createCriteria().andClubIdEqualTo(clubId).andUidEqualTo(uid).andIsTeamMemberEqualTo(Constants.YES);
            int count = clubMemberMapper.countByExample(example);
            if (count <= 0){
                return false;       //此成员不是代表队成员，不能编辑
            }
            TbClubMember tbClubMember = new TbClubMember();
            tbClubMember.setTeamLabelName(label);
            ret = clubMemberMapper.updateByExampleSelective(tbClubMember, tbClubMemberExample);
        }

        //更新索引
        if (ret == Constants.IS_YES){
            RespUserInfoBase user = getUserInfoBase(uid);
            executor.submit(new ClubMemberSolrIndexThread(queryClubMember(uid, clubId), user.getNickName(), clubMemberSearchService, 3));
            //clubMemberSearchService.deleteDocById(clubId, uid);
            //insertClubMemberIndex(clubId, uid);
        }

        boolean isExist = clubXpLevelService.isExistClubExperienceHistory(EDIT_MEMBER,clubId);
        if (ret == Constants.IS_YES  && !isExist){
            //添加俱乐部经验
            MqRequestMsg mqRequestMsg = new MqRequestMsg();
            RespClubXpLevelMsg respClubXpLevelMsg = new RespClubXpLevelMsg();
            respClubXpLevelMsg.setClubId(clubId);
            respClubXpLevelMsg.setExpName(EDIT_MEMBER);
            mqRequestMsg.setMsgId(UUID.randomUUID().toString());
            mqRequestMsg.setTopic(MqConstants.CLUB_XP_LEVEL_TOPIC_NAME);
            mqRequestMsg.setFlag(0);
            mqRequestMsg.setTag(MqConstants.CLUB_XP_LEVEL_TAGS_NAME);
            mqRequestMsg.setBody(ObjectUtil.toByteArray(respClubXpLevelMsg));
            clubXpLevelProducer.syncSend(mqRequestMsg);
        }
        return ret == Constants.IS_YES;
    }

    /**
     * 搜索俱乐部成员
     * @param clubId        俱乐部id
     * @param nickName      俱乐部成员昵称名关键字
     * @return
     */
    @Override
    public List<RespClubMember> searchClubMember(Integer clubId, String nickName, boolean showFund) {
        List<RespClubMember> list = new ArrayList<>();
        ReqClubMemberInfo searchInfo = new ReqClubMemberInfo();
        searchInfo.setClub_id(clubId);
        searchInfo.setClub_member_nickname(nickName);
        searchInfo.setPageSize(1000);
        APIResponse<List<ClubMemberResponse>> response = clubMemberSearchService.searchClubMemberInfoList(searchInfo);
        if (response.isRet()){
            List<ClubMemberResponse> searchResult = response.getData();
            for (ClubMemberResponse m : searchResult){
                Integer uid = Integer.valueOf(m.getClub_member_uid());
                RespClubMember respClubMember = new RespClubMember();
                respClubMember.setClubId(m.getClub_id());
                respClubMember.setUid(uid);
                respClubMember.setUsername(m.getClub_member_nickname());
                RespUserInfoBase userInfoBase = getUserInfoBase(uid);
                if (userInfoBase != null) {
                    respClubMember.setAvatar(userInfoBase.getIcon());
                    respClubMember.setUsername(userInfoBase.getNickName());
                    Integer gender = userInfoBase.getGender();
                    gender = gender == null?0:gender;
                    respClubMember.setGender(gender);
                }
                TbClubMember tbClubMember = this.getClubMember(uid, clubId);
                if (tbClubMember != null) {
                    respClubMember.setPriority(tbClubMember.getPriority());
                    respClubMember.setRoleCode(tbClubMember.getRoleCode());
                    respClubMember.setRoleName(tbClubMember.getRoleName());
                    respClubMember.setTeamMember(tbClubMember.getIsTeamMember()==1);
                    respClubMember.setTeamLabelName(tbClubMember.getTeamLabelName());
                    respClubMember.setMemberLabelName(tbClubMember.getMemberLabelName());
                    respClubMember.setRemarkname(tbClubMember.getRemarkName());
                }
                if (showFund){
                    TbClubOnlineMemberAccount onlineMemberAccount = clubFinanceMgmService.getClubMemberOnlineAccount(Integer.valueOf(m.getClub_member_uid()), m.getClub_id());
                    if (onlineMemberAccount != null) {
                        respClubMember.setOnlineFund(onlineMemberAccount.getMoneyTotal());
                    }
                    TbClubOfflineMemberAccount offlineMemberAccount = clubFinanceMgmService.getClubMemberOfflineAccount(Integer.valueOf(m.getClub_member_uid()), m.getClub_id());
                    if (offlineMemberAccount != null) {
                        respClubMember.setOfflineFund(offlineMemberAccount.getMoneyTotal());
                    }
                }
                list.add(respClubMember);
            }
        }
        return list;
    }



    /**
     * 添加俱乐部代表队成员
     * @param clubId        俱乐部ID
     * @param uids          俱乐部成员id，多个俱乐部成员用,隔开
     * @return
     */
    @Override
    public APIResponse addClubTeamMember(Integer clubId, List<Integer> uids) {
        TbClub club = clubMapper.selectByPrimaryKey(clubId);
        for (Integer uid : uids){
            if (!canJoinClubTeam(uid, clubId)){
                RespUserInfoBase userInfoBase = getUserInfoBase(uid);
                return APIResponse.returnFail("成员" + userInfoBase==null?"":userInfoBase.getNickName() + "已经加入了"+club.getSportName()+"类型俱乐部的代表队了！");
            }
        }
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId)
                .andUidIn(uids)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        TbClubMember member = new TbClubMember();
        member.setIsTeamMember(Constants.YES);
        int ret = clubMemberMapper.updateByExampleSelective(member, example);
        boolean isExist = clubXpLevelService.isExistClubExperienceHistory(CREATE_TEAM,clubId);
        if (ret > 0 && !isExist){
            //添加俱乐部经验
            MqRequestMsg mqRequestMsg = new MqRequestMsg();
            RespClubXpLevelMsg respClubXpLevelMsg = new RespClubXpLevelMsg();
            respClubXpLevelMsg.setClubId(clubId);
            respClubXpLevelMsg.setExpName(CREATE_TEAM);
            mqRequestMsg.setMsgId(UUID.randomUUID().toString());
            mqRequestMsg.setTopic(MqConstants.CLUB_XP_LEVEL_TOPIC_NAME);
            mqRequestMsg.setFlag(0);
            mqRequestMsg.setTag(MqConstants.CLUB_XP_LEVEL_TAGS_NAME);
            mqRequestMsg.setBody(ObjectUtil.toByteArray(respClubXpLevelMsg));
            clubXpLevelProducer.syncSend(mqRequestMsg);
        }
        return APIResponse.returnSuccess();
    }

    /**
     * 裁剪俱乐部代表队成员
     * @param clubId        俱乐部ID
     * @param uids          俱乐部成员id，多个俱乐部成员用,隔开
     * @return
     */
    @Override
    public Boolean cutClubTeamMember(Integer clubId, List<Integer> uids) {
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId)
                .andUidIn(uids)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        TbClubMember member = new TbClubMember();
        member.setIsTeamMember(Constants.NO);
        member.setTeamLabelName(""); //代表队标签也清掉
        int ret = clubMemberMapper.updateByExampleSelective(member, example);
        return ret > 0;
    }

    /**
     * 判断一个成员是否可以加入此类型的俱乐部的代表队
     */
    @Override
    public boolean canJoinClubTeam(int uid, int clubId){
        TbClub club = clubMapper.selectByPrimaryKey(clubId);
        if (club == null){
            return false;
        }
        Integer sportTypeId = club.getClubType(); //要加入的俱乐部运动类型

//        TbClubMemberExample example = new TbClubMemberExample();
//        example.createCriteria()
//                .andUidEqualTo(uid).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
//        List<TbClubMember> clubMembers = clubMemberMapper.selectByExample(example); //我已经加入的俱乐部
//        if(null != clubMembers && clubMembers.size() > 0)
//        {
//            for (TbClubMember tbClubMember : clubMembers) {
//                TbClub tbClub = clubMapper.selectByPrimaryKey(tbClubMember.getClubId());
//                if(null == tbClub)
//                {
//                    continue;
//                }
//                if (tbClub.getClubType().intValue() == sportTypeId && tbClubMember.getIsTeamMember() == 1) {
//                    //已经加入此类型俱乐部的代表队了
//                    logger.warn("已经加入过了" + JSON.toJSONString(tbClub));
//                    return false;
//                }
//            }
//        }

        int count = clubActivityMapper.countMember(clubId);
        logger.warn("count sportTypeId" + count + sportTypeId);
        if (sportTypeId == 3 && count < 22){      //足球代表队上线人数 22
            return true;
        }else if (sportTypeId == 1 && count < 16){      //篮球代表队上线人数 16
            return true;
        }else if ((sportTypeId == 2 || sportTypeId == 4) && count < 8){      //羽毛球代表队上线人数 8
            return true;
        }else {     //其它类型代表队成员人数上线12 人
            return (count<12 ? true : false);
        }
    }

    /**
     * 发送俱乐部勋章推送消息
     * @param clubId
     * @param uid
     * @param clubMedalId
     * @param categoryId
     * @return
     */
    public MqResponse sendClubMedalMqMsg(Integer clubId,Integer uid,Integer clubMedalId,Integer categoryId){
        if (categoryId.equals(SysCategoryEnum.FOOTBALL.getId())) {
            clubMedalId = SysClubMedalConditionEnum.FOOTBALL_LIVELY.getId();
        }else if(categoryId.equals(SysCategoryEnum.BASKETBALL.getId())){
            clubMedalId = SysClubMedalConditionEnum.BASKETBALL_LIVELY.getId();
        }else if (categoryId.equals(SysCategoryEnum.TENNIS.getId())){
            clubMedalId = SysClubMedalConditionEnum.TENNIS_LIVELY.getId();
        }else if (categoryId.equals(SysCategoryEnum.BADMINTON.getId())){
            clubMedalId = SysClubMedalConditionEnum.BADMINTON_LIVELY.getId();
        }else if (categoryId.equals(SysCategoryEnum.RUN.getId())){
            clubMedalId = SysClubMedalConditionEnum.RUN_LIVELY.getId();
        }else if (categoryId.equals(SysCategoryEnum.CYCLING.getId())){
            clubMedalId = SysClubMedalConditionEnum.CYCLING_LIVELY.getId();
        }else if (categoryId.equals(SysCategoryEnum.OUTDOORS.getId())){
            clubMedalId = SysClubMedalConditionEnum.OUTDOORS_LIVELY.getId();
        }
        MqRequestMsg mqRequestMsg = new MqRequestMsg();
        mqRequestMsg.setTopic(MqConstants.ClubMedalConsumer.CLUB_MEDAL_TOPIC);
        mqRequestMsg.setTag(MqConstants.ClubMedalConsumer.CLUB_MEDAL_TAGS);
        mqRequestMsg.setMsgId(String.valueOf(System.currentTimeMillis()));

        ClubMedalMsg clubMedalMsg = new ClubMedalMsg();
        clubMedalMsg.setMedalId(clubMedalId);
        clubMedalMsg.setCategoryId(categoryId);
        clubMedalMsg.setClubId(clubId);
        clubMedalMsg.setUid(uid);
        mqRequestMsg.setBody(ObjectUtil.toByteArray(clubMedalMsg));
        logger.info("俱乐部勋章的mq消息：{}", mqRequestMsg.toString());
        MqResponse response = this.clubMedalProducerImpl.syncSend(mqRequestMsg);
        logger.info("俱乐部勋章的mq消息发送结果：{}", response.getMqSendStatus());
        return response;
    }

    @Override
    public TbClubMember queryClubMember(int uid, int clubId) {
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andUidEqualTo(uid)
                .andClubIdEqualTo(clubId)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);

        List<TbClubMember> list = clubMemberMapper.selectByExample(example);
        if (list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }

    /**
     * 编辑俱乐部成员
     * @param currentUid    操作者uid
     * @param reqEdit       编辑内容
     * @version 2.1.1
     */
    @Override
    public void editClubMemberAll(Integer currentUid, ReqClubMemberEditAll reqEdit) {
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andClubIdEqualTo(reqEdit.getClubId())
                .andUidEqualTo(currentUid)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> members = clubMemberMapper.selectByExample(example);
        if (members == null || members.size() == 0){    //不是此俱乐部成员
            throw new BizException("非法操作！");
        }
        TbClubMember  currentMember = members.get(0);   //当前用户

        example.clear();
        example.createCriteria()
                .andClubIdEqualTo(reqEdit.getClubId())
                .andUidEqualTo(reqEdit.getUid())
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> memberList = clubMemberMapper.selectByExample(example);
        if (memberList == null || memberList.size() == 0){
            throw new BizException("被编辑的俱乐部成员已经退出此俱乐部！");
        }
        TbClubMember editMember = memberList.get(0);    //被编辑的成员

        String remarkName = reqEdit.getRemarkName();
        String label = reqEdit.getLabel();
        if (remarkName != null && !editMember.getRemarkName().equals(remarkName)) {  //编辑备注名
            if (currentMember.getPriority() > editMember.getPriority()){
                throw new BizException("没有权限编辑！");
            }
            editMember.setRemarkName(remarkName);
        }
        if (label != null && !editMember.getMemberLabelName().equals(label)) {  //编辑标签
            if (currentMember.getPriority() > editMember.getPriority()){
                throw new BizException("没有权限编辑！");
            }
            editMember.setMemberLabelName(label);
        }

        String roleCode = reqEdit.getRoleCode();
        if (!StringUtil.isBlankOrNull(roleCode) && !editMember.getRoleCode().equals(roleCode)){ //编辑角色
            TbClub tbClub = clubMapper.selectByPrimaryKey(editMember.getClubId());
            if (currentUid != tbClub.getUid().intValue()){
                throw new BizException("俱乐部主席才可以修改成员权限哦~");
            }
            if (currentUid == tbClub.getUid().intValue()
                    && currentUid == editMember.getUid().intValue()){
                throw new BizException("俱乐部主席不能修改自己的角色！");
            }
            editMember.setRoleCode(roleCode);
            editMember.setRoleName(reqEdit.getRoleName());
            editMember.setPriority(getClubMemberPriority(roleCode));
        }

        int ret = clubMemberMapper.updateByPrimaryKey(editMember);
        if (ret == 1) {
            RespUserInfoBase user = getUserInfoBase(reqEdit.getUid());
            if (user != null)       //更新索引
                executor.submit(new ClubMemberSolrIndexThread(editMember, user.getNickName(), clubMemberSearchService, 3));
        }
    }

    private int getClubMemberPriority(String roleCode){
        if (Constants.ClubRole.CLUB_ROLE_PRESIDENT.equals(roleCode)){
            return ClubMemberPriorityConstants.ROLE_CLUB_PRESIDENT_PRIORITY;
        }
        if (Constants.ClubRole.ROLE_CLUB_FINANCIAL.equals(roleCode)){
            return ClubMemberPriorityConstants.ROLE_CLUB_FINANCIAL_PRIORITY;
        }
        if (Constants.ClubRole.ROLE_CLUB_ADMIN.equals(roleCode)){
            return ClubMemberPriorityConstants.ROLE_CLUB_ADMIN_PRIORITY;
        }
        else return ClubMemberPriorityConstants.ROLE_CLUB_MEMBER_PRIORITY;
    }

    @Autowired
    private TbClubMemberQuitRecordMapper clubMemberQuitRecordMapper;

    private void recordClubMemberQuit(int clubId, int uid, String remark, boolean quit){

        Date monthBegin = DateUtils.getTimesMonthmorning();
        Date monthEnd = DateUtils.getTimesMonthnight();

        TbClubMemberQuitRecordExample example = new TbClubMemberQuitRecordExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId).andUidEqualTo(uid)
                .andCreateTimeGreaterThanOrEqualTo(monthBegin)
                .andCreateTimeLessThan(monthEnd);

        List<TbClubMemberQuitRecord> recordList = clubMemberQuitRecordMapper.selectByExample(example);
        if (recordList == null || recordList.size() == 0){
            TbClubMemberQuitRecord record = new TbClubMemberQuitRecord();
            record.setClubId(clubId);
            record.setUid(uid);
            record.setQuitCount(1);
            record.setCreateTime(new Date());
            record.setUpdateTime(new Date());
            record.setRemark(remark);
            clubMemberQuitRecordMapper.insertSelective(record);
        } else {
            TbClubMemberQuitRecord record = recordList.get(0);
            record.setQuitCount(record.getQuitCount()+1);
            record.setRemark(remark);
            clubMemberQuitRecordMapper.updateByExampleSelective(record, example);
        }

        //调整俱乐部积分
        if (quit) {
            clubIntegralService.joinClubCountSum(clubId, 1);
        }
    }

    /**
     * 更新俱乐部成员索引，更新
     * @param uid       用户id
     */
    @Override
    public void updateClubMemberIndex(int uid){
        RespUserInfoBase userInfo = getUserInfoBase(uid);
        if (userInfo == null){
            return;
        }
        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria().andUidEqualTo(uid).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> clubMembers = clubMemberMapper.selectByExample(example);
        if(clubMembers == null || clubMembers.size() == 0){
            return;
        }
        for (TbClubMember clubMember : clubMembers) {
            executor.submit(new ClubMemberSolrIndexThread(clubMember, userInfo.getNickName(), clubMemberSearchService, 3));
        }
    }

    @Override
    public void updateMemberIndexOfClub(int clubId){

        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria().andClubIdEqualTo(clubId).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> clubMembers = clubMemberMapper.selectByExample(example);
        if(clubMembers == null || clubMembers.size() == 0){
            return;
        }
        List<Integer> uids = new ArrayList<>();
        for (TbClubMember clubMember : clubMembers) {
            uids.add(clubMember.getUid());
        }
        Map<Integer, RespUserInfoBase> userInfos = userServiceFacade.batchQueryUserInfoToMap(uids);
        for (TbClubMember clubMember : clubMembers) {
            RespUserInfoBase userInfo = userInfos.get(clubMember.getUid());
            if (userInfo == null){
                continue;
            }
            executor.submit(new ClubMemberSolrIndexThread(clubMember, userInfo.getNickName(), clubMemberSearchService, 3));
        }
    }
}
